from django.shortcuts import render,redirect
#导包
from django.http import HttpResponse,HttpResponseRedirect,JsonResponse
#导入类视图
from django.views import View

#from myapp.models import User
import json
from django.core.serializers import serialize
from rest_framework.response import Response
from rest_framework.views import APIView
#导入加密库
import hashlib
#导入图片库
#绘画库
from PIL import ImageDraw
#字体库
from PIL import ImageFont
#图片库
from PIL import Image
#随机库
import random
#文件流
import io

import requests

#导入上传文件夹配置
from mydjango.settings import UPLOAD_ROOT
import os

#导入原生sql模块
from django.db import connection

import jwt

#导入redis数据库
import redis

#导入时间模块
import time

#导入公共目录变量
from mydjango.settings import BASE_DIR

#导包
from django.db.models import Q,F

#导入dwebsocket的库
from dwebsocket.decorators import accept_websocket
import uuid

from myapp.models import User,Cate,Pics,Goods,Comment,UserFlow
from myapp.myser import CateSer,UserSer,PicsSer,GoodsSer,CommentSer

import base64
import hmac
from hashlib import sha256
import urllib


#导包
import redis

#定义ip地址和端口
host = "127.0.0.1"
port = 6379

#链接对象
r = redis.Redis(host=host, port=port)


import pymongo

# 建立mongo连接对象
mongo_client = pymongo.MongoClient(host="localhost",port=27017)

# 导入bson
from bson import json_util as jsonb


# 商品检索接口
class GoodsSearch(APIView):
	def get(self,request):

		# 接收参数
		word = request.GET.get("word",None)
		print(word)
		
		# 检索
		# 翻译sql   select * from goods where (name.like '%word%' or desc like '%word%') and (parms like '%word%')
		goodslist = Goods.objects.filter(
			Q(name__icontains=word) | Q(desc__icontains=word))
	
		# 序列化、
		goods_ser = GoodsSer(goodslist,many=True)

		return Response(goods_ser.data)

		

		


# 工具方法,获取前n名的数据
def get_top_n(num):
	# 获取redis中的数据
	goods_click = r.zrange('good_rank', 0, -1, desc=True, withscores=True)[:num]
	# 获取mysql中数据
	goods = Goods.objects.in_bulk([int(item[0]) for item in goods_click])

	# 合并操作
	res = []

	for item in goods_click:

		# 遍历列表
		# 捕获异常，防止mysql和redis中数据不同步
		try:
			res.append({int(item[1]):goods[int(item[0])]})
		
		except Exception as e:
			pass

	# print(res)

	return res


# 商品排行榜数据视图
class GoodRank(APIView):
	def get(self, request):
		# 获取前n名的数据
		get_res = get_top_n(10)

		res = []
		# 遍历进行序列化
		for dic in get_res:
			for k,v in dic.items():
				# 序列化
				data = GoodsSer(v).data
				# 将商品点击数附加到商品序列化数据中
				data['clicks'] = k
				res.append(data)
		
		# 返回
		return Response(res)


# 新的商品参与排名
class GoodsClick(APIView):
	def get(self,request):
		# 接收参数
		id = request.GET.get("id",None)

		# 修改商品的点击数
		r.zincrby("good_rank",1,int(id))

		get_top_n(10)

		return Response({"message":"访问加1"})


# 对结果集美化
def dictfetchall(cursor):

	# 获取游标描述
	desc = cursor.description

	return [

		dict(zip([col[0] for col in desc], row))

		for row in cursor.fetchall()

	] 


# 商品关注接口（查询用户关注过的商品列表）
class UidFlow(View):
	def get(self,request):
		uid = request.GET.get("uid",None)

		# 建立游标对象
		cursor = connection.cursor()

		# 执行sql语句
		cursor.execute('select a.id,a.name,a.create_time from goods a left join userflow b on a.id = b.gid where b.uid = %s' % str(uid))

		# 获取结果
		# result = cursor.fetchall()
		result = dictfetchall(cursor)

		# 返回结果 手动序列化
		return HttpResponse(json.dumps(result,ensure_ascii=False,indent=4,default=str),content_type='application/json')


# 关注商品接口（取消关注）
class GetFlow(APIView):
	def get(self, request):
		id = request.GET.get('id', None)
		uid = request.GET.get('uid', None)
		type = request.GET.get('type', 1)

		if(int(type) == 1):

			# 关注
			userflow = UserFlow(gid=int(id), uid=int(uid))
			try:
				userflow.save()
				message = "关注成功"
				goods = Goods.objects.filter(id=int(id)).first()
				goods.flow = goods.flow + 1
				goods.save()
			except Exception as e:
				message = "不能重复关注"
				pass

		elif int(type) == 0:
			# 取关
			UserFlow.objects.filter(gid=int(id), uid=int(uid)).delete()
			message = "取关成功"
			goods = Goods.objects.filter(id=int(id)).first()
			goods.flow = goods.flow - 1
			goods.save()

		# 批量去关
		else:
			ids = request.GET.get("ids", None)
			# 批量操作
			UserFlow.objects.filter(uid=int(uid)).delete()
			# 强转
			id_list = eval(ids)
			for id in id_list:
				userflow = UserFlow(gid=int(id), uid=int(uid))
				userflow.save()
			message = "批量关注成功"

		return Response({"message": message})


# 用户列表
class UserList(APIView):
	def get(self,request):
		# 查询
		user = User.objects.filter()
		# 序列化
		user_ser = UserSer(user,many=True)
		return Response(user_ser.data)


# 评论列表
class CommentList(APIView):
	def get(self,request):

		# 商品id
		id = request.GET.get('id',None)
		
		# 查询评论
		comment = Comment.objects.filter(gid=int(id)).order_by("-id")

		# 序列化
		comment_ser = CommentSer(comment,many=True)

		return Response(comment_ser.data)


# 反序列化入库（评论）
class InsertComment(APIView):
	def post(self,request):

		# 如果redis有值证明没有过期，可以评论
		if r.get("uid"):
			return Response({'code': 403, 'message': '您评论的太快了，请歇一歇'})

		# 初始化参数
		comment = CommentSer(data=request.data)
		
		# 数据校验
		if comment.is_valid():
			# 数据入库
			comment.save()
			# 插入评论标记
			r.set('uid','123')
			r.expire('uid',30)

		return Response({'code':200,'message':'入库成功'})
		






# 统计在线人数
class GetOnLine(APIView):
	def get(self,request):
		# 获取客户ip
		if 'HTTP_X_FORWARDED_FOR' in request.META:
			ip = request.META.get('HTTP_X_FORWARDED_FOR')
		else:
			ip = request.META.get('REMOTE_ADDR')
		
		# 对用户ip进行存储
		r.sadd("online",ip)

		# 设置超时时间 秒
		r.expire("online",20)

		# 获取在线人数的数量
		myset = r.smembers('online')

		# 返回数据
		return Response({'online':len(myset)})


# 获取商品标签
class GetTags(View):
	def get(self,request):
		id = request.GET.get('id', None)
		# 建立数据库对象
		db = mongo_client.md
		# 建立表对象
		table = db.mytag

		# 查询数据
		res = table.find_one({'gid':str(id)})

		return HttpResponse(jsonb.dumps(res,ensure_ascii=False))


# 商品标签添加接口
class InsertTags(APIView):
	def get(self,request):

		id = request.GET.get('id',None)
		tags = request.GET.get('tags', None)

		# 字符串转列表
		tags = tags.split(",")

		# 列表转字符串
		# tags = ",".join(tags)
		# print(tags)

		# 建立数据库对象
		db = mongo_client.md
		# 建立表对象
		table = db.mytag

		# 排重操作
		# 查询
		res = table.find({"gid":str(id)}).count()
		if res>0:
			return Response({'message':'重复数据'})
		else:
			# 入库
			table.insert({'gid':str(id),'tags':tags})
			return Response({'message':'入库成功'})

#商品信息接口
class GoodInfo(APIView):

	def get(self, request):

		id = int(request.GET.get("id", 0))

		#查询数据
		good = Goods.objects.get(id=id)

		#序列化操作
		good_ser = GoodsSer(good)

		return Response(good_ser.data)


#商品列表页
#商品列表页
class GoodsList(APIView):

	def get(self, request):
		#当前页
		page = int(request.GET.get("page", 1))
		#一页有多少条商品
		size = int(request.GET.get("size", 1))

		#定义从哪儿开始切
		data_start = (page-1) * size

		#定义切到哪儿
		data_end = page * size

		#查询数据
		goodslist = Goods.objects.all()[data_start:data_end]

		#查询总数量
		count = Goods.objects.count()

		#序列化操作
		goods_ser = GoodsSer(goodslist, many=True)

		res = {}
		res['total'] = count
		res['data'] = goods_ser.data
		return Response(res)


#更新商品
class UpdataGoods(APIView):

	def get(self, request):

		#接收参数  dict['username']
		name = request.GET.get('name', 'null')
		desc = request.GET.get('desc', 'null')
		parms = request.GET.get('parms', 'null')
		cate_id = request.GET.get('cate_id', 'null')
		price = request.GET.get('price', 'null')
		id = request.GET.get('id', 'null')

		#查询
		goods = Goods.objects.filter(id=int(id)).first()

		#修改属性
		goods.name = name
		goods.desc = desc
		goods.cate_id = int(cate_id)
		goods.parms = parms
		goods.price = int(price)
		goods.save()

		res = {}
		res['code'] = 200
		res['id'] = goods.id
		res['message'] = '恭喜，修改成功'

		return Response(res)


#添加商品
class InsertGoods(APIView):

	def get(self, request):

		#接收参数  dict['username']
		name = request.GET.get('name', 'null')
		desc = request.GET.get('desc', 'null')
		parms = request.GET.get('parms', 'null')
		cate_id = request.GET.get('cate_id', 'null')
		price = request.GET.get('price', 'null')

		#排重
		goods = Goods.objects.filter(name=name).first()

		if goods:
			res = {}
			res['code'] = 405
			res['message'] = '该商品已存在'
			return Response(res)

		#入库
		goods = Goods(name=name, desc=desc, cate_id=cate_id,
		              parms=parms, price=price)
		goods.save()

		#查询商品id
		goods = Goods.objects.filter(name=name).first()

		res = {}
		res['code'] = 200
		res['id'] = goods.id
		res['message'] = '恭喜，添加成功'

		return Response(res)
